﻿namespace NTLib.Core.Threading
{
    using NTLib.Core.ScopeLock;
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Extensions methods for the SemaphoneSlim object.
    /// </summary>
    public static class SemaphoreSlimExtensions
    {
        /// <summary>
        /// Blocks the current thread until it can enter the System.Threading.SemaphoreSlim
        /// Scopes the wait.
        /// </summary>
        public static ScopeLockItem<SemaphoreSlim> ScopeWait(this SemaphoreSlim t, CancellationToken token = default(CancellationToken))
        {
            try
            {
                t.Wait(token);
            }
            catch (ObjectDisposedException)
            {

            }
            return new ScopeLockItem<SemaphoreSlim>(t, (sme) =>
            {
                try
                {
                    t.Release();
                }
                catch (ObjectDisposedException)
                {

                }
            });
        }

        /// <summary>
        /// Blocks the current thread until it can enter the System.Threading.SemaphoreSlim
        /// Scopes the wait.
        /// </summary>
        public static async Task<ScopeLockItem<SemaphoreSlim>> ScopeWaitAsync(this SemaphoreSlim t, CancellationToken token = default(CancellationToken))
        {
            try
            {
                await Task.Run(() => t.Wait(token));
            }
            catch (ObjectDisposedException)
            {

            }
            return new ScopeLockItem<SemaphoreSlim>(t, (sme) =>
            {
                try
                {
                    t.Release();
                }
                catch (ObjectDisposedException)
                {

                }
            });
        }
    }
}
